package org.robotlegs.xxl.modular.mvcs 
{
	import flash.display.DisplayObjectContainer;
	import flash.system.ApplicationDomain;
	import org.robotlegs.core.IInjector;
	import org.robotlegs.core.IMediatorMap;
	import org.robotlegs.xxl.base.ContextSignal;
	import org.robotlegs.xxl.base.MediatorMap;
	import org.robotlegs.xxl.base.SignalCommandMap;
	import org.robotlegs.xxl.core.ISignalCommandMap;
	import org.robotlegs.xxl.modular.base.ModuleCommandMap;
	import org.robotlegs.xxl.modular.base.ModuleContextSignal;
	import org.robotlegs.xxl.modular.base.ModuleSignalMap;
	import org.robotlegs.xxl.modular.core.IModuleCommandMap;
	import org.robotlegs.xxl.modular.core.IModuleContext;
	import org.robotlegs.xxl.modular.core.IModuleSignalMap;
	import org.robotlegs.xxl.mvcs.Context;
	
	/**
	 * ...
	 * @author XXL
	 */
	public class ModuleContext extends Context implements IModuleContext 
	{
		protected var _applicationDomain:ApplicationDomain;
		
		protected var _moduleSignalMap:IModuleSignalMap;
		protected var _moduleCommandMap:IModuleCommandMap;
		
		public function ModuleContext(contextView:DisplayObjectContainer = null, autoStartup:Boolean = true, parentInjector:IInjector = null, applicationDomain:ApplicationDomain = null) 
		{
			_applicationDomain = applicationDomain || ApplicationDomain.currentDomain;
			if (parentInjector)
			{
				_injector = parentInjector.createChild(_applicationDomain);
			}
			super(contextView, autoStartup);
		}
		
		override protected function mapInjections():void 
		{
			super.mapInjections();
			injector.mapClass(IModuleSignalMap, ModuleSignalMap);
			injector.mapValue(IModuleCommandMap, moduleCommandMap);
		}
		
		//override protected function unmapInjections():void
		//{
			//super.unmapInjections();
			//injector.unmap(IModuleSignalMap);
			//injector.unmap(IModuleCommandMap);
		//}
		
		protected function get moduleSignalMap():IModuleSignalMap 
		{
			if (_isDispose)
			{
				return _moduleSignalMap;
			}
			return _moduleSignalMap ||= new ModuleSignalMap(this, injector, reflector);
		}
		
		protected function set moduleSignalMap(value:IModuleSignalMap):void 
		{
			_moduleSignalMap = value;
		}
		
		protected function get moduleCommandMap():IModuleCommandMap 
		{
			if (_isDispose)
			{
				return _moduleCommandMap;
			}
			return _moduleCommandMap ||= new ModuleCommandMap(injector, reflector, moduleSignalMap);
		}
		
		protected function set moduleCommandMap(value:IModuleCommandMap):void 
		{
			_moduleCommandMap = value;
		}
		
		override protected function get signalCommandMap():ISignalCommandMap 
		{
			if (_isDispose)
			{
				return _signalCommandMap;
			}
			return _signalCommandMap ||= new SignalCommandMap(injector.createChild(_applicationDomain), reflector, signalMap);
		}
		
		override protected function get mediatorMap():IMediatorMap 
		{
			if (_isDispose)
			{
				return _mediatorMap;
			}
			return _mediatorMap ||= new MediatorMap(contextView, injector.createChild(_applicationDomain), reflector);
		}
		
		/* INTERFACE org.robotlegs.xxl.modular.core.IModuleContext */
		
		public function dispose():void 
		{
			_isDispose = true;
			var contextSignal:ContextSignal = injector.getInstance(ContextSignal);
			contextSignal.dispatch(ContextSignal.SHUTDOWN, this);
			contextSignal.removeAll();
			contextSignal = null;
			
			_moduleCommandMap.unmapSignals();
			_moduleSignalMap.unmapSignals();
			_moduleSignalMap.dispose();
			_moduleCommandMap = null;
			_moduleSignalMap = null;
			_applicationDomain = null;
			
			_injector = null;
			_reflector = null;
			_signalCommandMap = null;
			_mediatorMap = null;
			_viewMap = null;
			_signalMap = null;
			_contextView = null;
		}
		
	}

}